package com.open.capacity.workflow.service.impl;


import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.open.capacity.commons.CodeEnum;
import com.open.capacity.commons.PageResult;
import com.open.capacity.commons.Result;
import com.open.capacity.model.system.LoginAppUser;
import com.open.capacity.reimburse.util.uuid.UUIDUtils;
import com.open.capacity.utils.PageUtil;
import com.open.capacity.workflow.dao.WFTaskDao;
import com.open.capacity.workflow.dao.WFTaskHistoryDao;
import com.open.capacity.workflow.model.WFEngine.WFAuditor;
import com.open.capacity.workflow.model.WFSchemeinfo;
import com.open.capacity.workflow.model.WFTask;
import com.open.capacity.workflow.service.WFTaskHistoryService;
import com.open.capacity.workflow.service.WFTaskService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;


@Slf4j
@Service
public class WFTaskServiceImpl implements WFTaskService {

    @Autowired
    private WFTaskDao taskDao;

    @Autowired
    private WFTaskHistoryDao historyDao;


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void save(WFTask task) {

        taskDao.save(task);
        log.info("保存流程任务：{}", task);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void save(WFTask task, String companyId, String departmentId) {
        Date now = new Date();
        if (CollectionUtils.isNotEmpty(task.getAuditors())) {
            for (WFAuditor auditor : task.getAuditors()) {
                WFTask wfTaskEntity = new WFTask();
                wfTaskEntity.setId(UUIDUtils.getOriginalUUIDWithoutBar());
                wfTaskEntity.setProcessId(task.getProcessId());
                wfTaskEntity.setNodeId(task.getNodeId());
                wfTaskEntity.setNodeName(task.getNodeName());
                wfTaskEntity.setTaskType(task.getTaskType());
                wfTaskEntity.setTimeoutAction(task.getTimeoutAction());
                wfTaskEntity.setTimeoutNotice(task.getTimeoutNotice());
                wfTaskEntity.setPreviousId(task.getPreviousId());
                wfTaskEntity.setPreviousName(task.getPreviousName());
                wfTaskEntity.setCreateUserid(task.getCreateUserid());
                wfTaskEntity.setCreateUsername(task.getCreateUsername());

                wfTaskEntity.setAuditorId(auditor.getAuditorId());
                wfTaskEntity.setAuditorName(auditor.getAuditorName());

                wfTaskEntity.setCompanyId("1");
                wfTaskEntity.setDepartmentId("1");
                if (auditor.getCondition() != null && auditor.getCondition().equals(1))//1.同一个部门2.同一个公司
                {
                    wfTaskEntity.setDepartmentId(departmentId);
                } else if (auditor.getCondition() != null && auditor.getCondition().equals(2)) {
                    wfTaskEntity.setCompanyId(companyId);
                }

                wfTaskEntity.setIsFinished(0);
                wfTaskEntity.setCreateTime(now);
                taskDao.save(wfTaskEntity);
            }
        } else {
            task.setAuditorId("1");
            task.setId(UUIDUtils.getOriginalUUIDWithoutBar());
            task.setIsFinished(0);
            task.setCreateTime(now);
            taskDao.save(task);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void update(WFTask task) {
        taskDao.updateByOps(task);
        log.info("修改流程任务：{}", task);
    }

    @Override
    public void updateStatus(String id, Integer status, String userId, String userName) {

        WFTask task = new WFTask();
        task.setId(id);
        task.setIsFinished(status);
        task.setUpdateUserid(userId);
        task.setUpdateUsername(userName);
        task.setUpdateTime(new Date());
        taskDao.updateStatus(task);
        log.info("修改状态：{}", task);
    }

    @Override
    public void updateStatus(String processId, String nodeId, String taskId, String userId, String userName) {
        Map<String, Object> params = new HashMap<>();
        params.put("processId", processId);
        params.put("nodeId", nodeId);
        params.put("isFinished", 0);
        List<WFTask> list = taskDao.findList(params);
        Date now = new Date();
        if (CollectionUtils.isNotEmpty(list)) {
            for (WFTask item : list) {
                WFTask task = new WFTask();
                task.setId(item.getId());
                task.setIsFinished(1);
                task.setUpdateTime(now);
                if (taskId.equals(item.getId())) {
                    task.setUpdateUserid(userId);
                    task.setUpdateUsername(userName);
                }
                taskDao.updateStatus(task);
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(String id) {
        WFTask task = taskDao.findById(id);
        taskDao.delete(id);
        log.info("删除流程任务：{}", task);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteByProcessId(String processId) {
        taskDao.deleteByProcessId(processId);
        historyDao.deleteByProcessId(processId);
        log.info("删除流程实例：{}", processId);
    }

    @Override
    public void deleteByProcessIdNoHistory(String processId) {
        taskDao.deleteByProcessId(processId);
        log.info("删除流程实例：{}", processId);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteFinishedByUndoTaskByProcessId(String processId) {
        List<WFTask> tasks = taskDao.findByProcessId(processId);
        if (CollectionUtils.isNotEmpty(tasks)) {
            for (WFTask item : tasks) {
                if (item.getIsFinished().equals(0)) {
                    taskDao.delete(item.getId());
                }
            }
        }
    }


    @Override
    public WFTask findById(String id) {
        return taskDao.findById(id);
    }


    @Override
    public WFTask findUnFinishTasks(String processId, String nodeId) {
        Map<String, Object> params = new HashMap<>();
        params.put("processId", processId);
        params.put("nodeId", nodeId);
        params.put("isFinished", 0);
        List<WFTask> list = taskDao.findList(params);
        if (CollectionUtils.isNotEmpty(list)) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public List<WFTask> findUnFinishTasks(String processId) {
        Map<String, Object> params = new HashMap<>();
        params.put("processId", processId);
        params.put("isFinished", 0);
        List<WFTask> list = taskDao.findList(params);
        return list;
    }

    @Override
    public List<WFTask> findTasksByProcessId(String processId) {
        Map<String, Object> params = new HashMap<>();
        params.put("processId", processId);
        List<WFTask> list = taskDao.findList(params);
        return list;
    }

    @Override
    public WFTask findTasksByProcessCode(String code) {
        Map<String, Object> params = new HashMap<>();
        params.put("code", code);
        List<WFTask> list = taskDao.findList(params);
        if (CollectionUtils.isNotEmpty(list)) {
            return list.get(0);
        } else {
            return null;
        }
    }

    @Override
    public WFTask findTasksByProcessIdAndNodeId(String processId, String nodeId) {
        Map<String, Object> params = new HashMap<>();
        params.put("processId", processId);
        params.put("nodeId", nodeId);
        List<WFTask> list = taskDao.findList(params);
        if (CollectionUtils.isNotEmpty(list)) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public List<WFTask> findTasksByProcessIdAndPreviousId(String processId, String previousId) {
        Map<String, Object> params = new HashMap<>();
        params.put("processId", processId);
        params.put("previousId", previousId);
        return taskDao.findList(params);
    }

    @Override
    public PageResult<WFTask> pageTasks(Map<String, Object> params, LoginAppUser user) {
        //设置分页信息，分别是当前页数和每页显示的总记录数【记住：必须在mapper接口中的方法执行之前设置该分页信息】
        if (MapUtils.getInteger(params, "page") != null && MapUtils.getInteger(params, "limit") != null)
            PageHelper.startPage(MapUtils.getInteger(params, "page"), MapUtils.getInteger(params, "limit"), true);

        List<WFTask> list = taskDao.findList(params);
        PageInfo<WFTask> pageInfo = new PageInfo(list);

        return PageResult.<WFTask>builder().data(pageInfo.getList()).resp_code(CodeEnum.SUCCESS.getCode()).count(pageInfo.getTotal()).build();
    }

    @Override
    public List<WFTask> findTasks(Map<String, Object> params, LoginAppUser user) {
        List<WFTask> list = taskDao.findList(params);
        return list;
    }


    @Override
    public Result saveOrUpdate(WFTask task, String keyValue) {
        int i = 0;

        if (StringUtils.isNotEmpty(keyValue)) {
            WFTask model = taskDao.findById(keyValue);
            if (model != null) {
                task.setId(keyValue);
                i = taskDao.updateByOps(task);
            }
        } else {
            task.setId(UUIDUtils.getOriginalUUIDWithoutBar());
            i = taskDao.save(task);
        }

        return i > 0 ? Result.succeed("操作成功") : Result.failed("操作失败");
    }
}
